package org.dcarew.model.utils;

/**
 * General static utility methods.
 * 
 * @author Devon Carew
 */
public class CoreUtils
{
	
	private CoreUtils()
	{
		
	}
	
	/**
	 * Returns the string for the package of the given class, i.e. "java.lang".
	 * 
	 * @param clazz
	 * @return Returns the string for the package of the given class, i.e. "java.lang".
	 */
	@SuppressWarnings("unchecked")
	public static String getPackageName(Class clazz)
	{
		String className = clazz.getName();
		
		int index = className.lastIndexOf('.');
		
		return index == -1 ? null : className.substring(0, index);
	}
	
	/**
	 * Returns the short name of the given class, i.e. "java.lang.String" --&gt; "String".
	 * 
	 * @param clazz
	 * @return Returns the short name of the given class, i.e. "java.lang.String" --&gt; "String".
	 */
	@SuppressWarnings("unchecked")
	public static String getShortName(Class clazz)
	{
		String className = clazz.getName();
		
		int index = className.lastIndexOf('.');
		
		return index == -1 ? className : className.substring(index + 1);
	}
	
	/**
	 * Returns the result of calling the object's equals methods, properly handling nulls.
	 * 
	 * @param object1
	 * @param object2
	 * @return Returns the result of calling the object's equals methods, properly handling nulls.
	 */
	public static boolean safeEquals(Object object1, Object object2)
	{
		if (object1 == object2)
			return true;
		
		if (object1 == null || object2 == null)
			return false;
		
		return object1.equals(object2);
	}
	
	/**
	 * Returns the current Java version. Examples are 1.4, 1.5, and 1.6.
	 * 
	 * @return Returns the current Java version.
	 */
	public static double getMajorJavaVersion()
	{
		try
		{
			// java.version=1.4.2_12
			String version = System.getProperty("java.version");
			
			int index = version.lastIndexOf('.');
			
			return Double.parseDouble(index == -1 ? version : version.substring(0, index));
		}
		catch (NumberFormatException nfe)
		{
			return 0.0d;
		}
	}
	
	/**
	 * Returns the minor Java version. For example, on Java 1.4.2 this method would return 2.
	 * 
	 * @return Returns the minor Java version.
	 */
	public static int getMinorJavaVersion()
	{
		try
		{
			// java.version=1.4.2_12
			String version = System.getProperty("java.version");
			
			if (version.indexOf('-') != -1)
				version = version.substring(0, version.indexOf('-'));
			
			if (version.indexOf('_') != -1)
				version = version.substring(0, version.indexOf('_'));
			
			String[] values = version.split("\\.");
			
			if (values.length >= 3)
				return Integer.parseInt(values[2]);
			
			return 0;
		}
		catch (NumberFormatException nfe)
		{
			return 0;
		}
	}
	
	/**
	 * Returns the given text with the first letter capitolized.
	 * 
	 * @param text
	 * @return Returns the given text with the first letter capitolized.
	 */
	public static String capitalize(String text)
	{
		if (text == null || text.length() == 0)
			return text;
		
		String upper = Character.toString(Character.toTitleCase(text.charAt(0)));
		
		if (text.length() == 1)
			return upper;
		else
			return upper + text.substring(1);
	}
	
	/**
	 * @return Returns a few sentences of sample text.
	 */
	public static String getLoremIpsumText()
	{
		return "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
			+ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. " 
			+ "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " 
			+ "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
	}
	
	/**
	 * Returns sample text. The method will return approximately the amount of chars you ask for. The
	 * text will always be terminated by a period and will have no leading or trailing spaces.
	 * 
	 * @param charCount
	 * @return Returns sample text.
	 */
	public static String getLoremIpsumText(int charCount)
	{
		String lorem = getLoremIpsumText();
		
		while (lorem.length() < charCount)
		lorem += System.getProperty("line.separator") + getLoremIpsumText();
		
		lorem = lorem.substring(0, charCount - 1).trim();
		
		if (!lorem.endsWith("."))
			lorem += ".";
		
		return lorem;
	}
	
	/**
	 * Throw an UnsupportedOperationException with the name of the calling method.
	 */
	public static void throwNotImplemented()
	{
		String message = "Not implemented";
		
		StackTraceElement[] stackTrace = new Throwable().getStackTrace();
		
		if (stackTrace == null || stackTrace.length <= 1)
			throw new UnsupportedOperationException(message);
		else
			throw new UnsupportedOperationException(message + ": " + stackTrace[1].toString());
	}

	/**
	 * The same as calling Class.forName(), except instead of throwing a ClassNotFoundException,
	 * this method returns null.
	 * 
	 * @param className
	 *            the class to return
	 * @return the Class or null if it is not found
	 */
	@SuppressWarnings("unchecked")
	public static Class classForName(String className)
	{
		try
		{
			return Class.forName(className);
		}
		catch (ClassNotFoundException cnfe)
		{
			return null;
		}
	}
	
	/**
	 * Sleep the indicated number of milliseconds.
	 * 
	 * @param millis the milliseconds to sleep
	 */
	public static void sleepMillis(int millis)
	{
		try
		{
			Thread.sleep(millis);
		}
		catch (InterruptedException e)
		{
			throw new RuntimeException(e);
		}
	}
	
}
